﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LukeSkywalker.IPNetwork;

namespace System.Net.DnsToolkit.Scanner {
    public static class IPNetworkFilter {


        static string[] rfc =  { 
            "0.0.0.0/8", 
            "127.0.0/8", 
            "169.254.0.0/16", 
            "10.0.0.0/8", 
            "172.16.0.0/12", 
            "192.0.0.0/24", 
            "192.0.2.0/24", 
            // "192.88.99.0/24", 
            "192.168.0.0/16", 
            "198.18.0.0/15",
            "198.51.100.0/24",
            "203.0.113.0/24",
            "224.0.0.0/4",
            "240.0.0.0/4",
            "255.255.255.255/32"
        };

        // http://www.cymru.com/Documents/bogon-dd.html
        static string[] bogon =  {
            "0.0.0.0 255.0.0.0",
            "5.0.0.0 255.0.0.0",
            "10.0.0.0 255.0.0.0",
            "14.0.0.0 255.0.0.0",
            "23.0.0.0 255.0.0.0",
            "31.0.0.0 255.0.0.0",
            "36.0.0.0 254.0.0.0",
            "39.0.0.0 255.0.0.0",
            "42.0.0.0 255.0.0.0",
            "49.0.0.0 255.0.0.0",
            "100.0.0.0 252.0.0.0",
            "104.0.0.0 254.0.0.0",
            "106.0.0.0 255.0.0.0",
            "127.0.0.0 255.0.0.0",
            "169.254.0.0 255.255.0.0",
            "172.16.0.0 255.240.0.0",
            "176.0.0.0 254.0.0.0",
            "179.0.0.0 255.0.0.0",
            "181.0.0.0 255.0.0.0",
            "185.0.0.0 255.0.0.0",
            "192.0.2.0 255.255.255.0",
            "192.168.0.0 255.255.0.0",
            "198.18.0.0 255.254.0.0",
            "198.51.100.0 255.255.255.0",
            "203.0.113.0 255.255.255.0",
            "223.0.0.0 255.0.0.0",
            "224.0.0.0 224.0.0.0"
        };

        static List<IPNetwork> rfcs = rfc.Select(s => {
            return IPNetwork.Parse(s);
        }).ToList();


        static List<IPNetwork> bogons = bogon.Select(s => {
            return IPNetwork.Parse(s);
        }).ToList();

        public static bool IsFiltered(IPAddress network) {
            return IsRfcNetwork(network)
                || IsBogon(network);
        }

        static bool IsRfcNetwork(this IPAddress network) {
            foreach (IPNetwork rn in rfcs) {
                if (IPNetwork.Contains(rn, network)) {
                    return true;
                }
            }
            return false;
        }

        static bool IsBogon(this IPAddress network) {
            foreach (IPNetwork rn in bogons) {
                if (IPNetwork.Contains(rn, network)) {
                    return true;
                }
            }
            return false;
        }


        static void Test127001() {
            var ss = new[] { "126.255.255.255", "127.0.0.1", "127.255.255.255" };
            foreach (string s in ss) {
                var ipn = IPNetwork.ToUint(IPAddress.Parse(s));
                Console.WriteLine("{0} {1}", s, ipn);
            }

        }


    }
}
